<template>
  <div id="scale-container" ref="scale-container">
    <template v-if="ready">
      <slot />
    </template>
  </div>
</template>

<script>
import { debounce } from '@/utils';
import { getCurrentInstance, onMounted, nextTick, onUnmounted, ref } from 'vue';
export default {
	name : 'ScaleContainer',
	props : {
		options : Object,
	},
	setup (ctx) {
		let ready = ref(false);
		// 实际传入的大屏尺寸
		let w = 0;
		let h = 0;
		// 浏览器画布的尺寸
		let originalWidth = 0;
		let originalHeight = 0;
		// dom节点
		let dom = null;
		let observer;

		// 初始化
		let initSize = () => {
			// 同步函数
			return new Promise((resolve) => {
				nextTick(() => {
					// 获取画布的真实尺寸，只需要获取一次
					if (!originalWidth) {
						originalWidth = window.screen.width;
						originalHeight = window.screen.height;
					}
					/**
           * 大屏尺寸设置
           * 如果未传入实际的大屏尺寸，使用浏览器画布的尺寸
           */
					const { width, height } = ctx.options;
					if (ctx.options && width && height) {
						w = width;
						h = height;
					} else {
						w = originalWidth;
						h = originalHeight;
					}

					resolve();
				});
			});
		};

		// 给dom赋值
		let updateSize = () => {
			dom.style.width = `${w}px`;
			dom.style.height = `${h}px`;
		};

		// 缩放比例计算
		let updateScale = () => {
			// 获取可视区域的尺寸
			const currentWidth = document.body.clientWidth;
			const currentHeight = document.body.clientHeight;
			// 可视区域的尺寸/大屏尺寸(缩放比)
			const widthScale = currentWidth / w;
			const heightScale = currentHeight / h;
			dom && (dom.style.transform = `scale(${widthScale}, ${heightScale})`);
		};

		// 监听
		const initMutationObserver = () => {
			const MutationObserver = window.MutationObserver;
			observer = new MutationObserver(onResize);
			// 监听dom style 变化
			observer.observe(dom, {
				attributes : true,
				attributeFilter : ['style'],
				attributeOldValue : true,
			});
		};

		const removeMutationObserver = () => {
			if (observer) {
				observer.disconnect();
				observer.takeRecords();
				observer = null;
			}
		};

		let onResize = async () => {
			await initSize();
			updateSize();
			updateScale();
		};

		onMounted(async () => {
			ready.value = false;
			dom = getCurrentInstance().ctx.$refs['scale-container'];
			await initSize();
			updateSize();
			updateScale();
			window.addEventListener('resize', debounce(onResize, 100));
			initMutationObserver();
			ready.value = true;
		});

		// 解绑
		onUnmounted(() => {
			window.removeEventListener('resize', onResize);
			removeMutationObserver();
		});

		return {
			ready,
		};
	},
};
</script>

<style lang="scss" scoped>
#scale-container {
  position: fixed;
  left: 0;
  top: 0;
  overflow: hidden;
  transform-origin: left top;
  z-index: 999;
}
</style>
